import { OperatingSystem } from '../../utils';

import {
  IPtyExitEvent,
  IPtyProcessChangeEvent,
  IShellLaunchConfig,
  ITerminalConnection,
  ITerminalError,
  ITerminalInternalService,
  ITerminalProfile,
} from '../common';

export class TerminalInternalService implements ITerminalInternalService {

  constructor() {}

  /**
   * 生成终端 sessionId
   */
  generateSessionId(): Promise<string> {
    return window.electron.terminal.generateSessionId();
    // return generateSessionId() + TERMINAL_ID_SEPARATOR + generateSessionId();
  }

  /**
   * 获取终端选项
   */
  getOptions() {
    return window.electron.terminal.getOptions
      ? window.electron.terminal.getOptions()
      : {};
  }

  /**
   * 检查 sessionId 是否有效
   * @param sessionIds 终端 sessionId 列表
   */
  check(sessionIds: string[]) {
    return window.electron.terminal.check
      ? window.electron.terminal.check(sessionIds)
      : Promise.resolve(true);
  }

  /**
   * 向终端发送文本
   * @param sessionId 终端 sessionId
   * @param message 发送内容
   */
  async sendText(sessionId: string, message: string) {
    return window.electron.terminal.sendText(sessionId, message);
  }

  /**
   * 调整终端尺寸
   * @param sessionId 终端 sessionId
   * @param cols 列数
   * @param rows 行数
   */
  async resize(sessionId: string, cols: number, rows: number) {
    return window.electron.terminal.resize(sessionId, cols, rows);
  }

  /**
   * 根据 sessionId 销毁终端
   * @param sessionId 终端 sessionId
   */
  disposeById(sessionId: string) {
    return window.electron.terminal.disposeById(sessionId);
  }

  /**
   * 获取终端进程 id
   * @param sessionId 终端 sessionId
   */
  async getProcessId(sessionId: string) {
    return window.electron.terminal.getProcessId(sessionId);
  }

  /**
   * 监听终端错误事件
   * @param handler 错误处理函数
   */
  onError(handler: (error: ITerminalError) => void) {
    return window.electron.terminalEvents.onError((error) => {
      handler(error);
    });
  }

  /**
   * 监听终端退出事件
   * @param handler 退出事件处理函数
   */
  onExit(handler: (event: IPtyExitEvent) => void) {
    return window.electron.terminalEvents.onExit((event) => {
      handler(event);
    });
  }

  /**
   * 监听终端进程变更事件
   * @param handler 进程变更处理函数
   */
  onProcessChange(handler: (event: IPtyProcessChangeEvent) => void) {
    return window.electron.terminalEvents.onProcessChange((event) => {
      handler(event);
    });
  }

  /**
   * 获取当前操作系统类型
   */
  async getOS(): Promise<OperatingSystem> {
    return await window.electron.terminal.getOS();
  }

  /**
   * 获取终端 profile 列表
   * @param autoDetect 是否自动检测
   */
  async getProfiles(autoDetect: boolean): Promise<ITerminalProfile[]> {
    return await window.electron.terminal.getProfiles(autoDetect);
  }

  /**
   * 获取默认系统 shell 路径
   */
  async getDefaultSystemShell(): Promise<string> {
    return await window.electron.terminal.getDefaultSystemShell();
  }

  /**
   * 获取 code 平台 key
   */
  async getCodePlatformKey(): Promise<'osx' | 'windows' | 'linux'> {
    return await window.electron.terminal.getCodePlatformKey();
  }

  /**
   * 通过启动配置附加终端
   * @param sessionId 终端 sessionId
   * @param cols 列数
   * @param rows 行数
   * @param launchConfig 启动配置
   * @param xterm xterm 实例
   */
  async attachByLaunchConfig(
    sessionId: string,
    cols: number,
    rows: number,
    launchConfig: IShellLaunchConfig
    // xterm: IXTerm
  ): Promise<ITerminalConnection | undefined> {

    // 如果有自定义 pty 实现，使用扩展主机代理
    // if (launchConfig.customPtyImplementation) {
    //   const proxy = launchConfig.customPtyImplementation(
    //     sessionId,
    //     cols,
    //     rows
    //   ) as TerminalProcessExtHostProxy;
    //   proxy.start();
    //   proxy.onProcessExit(() => {
    //     this._processExtHostProxies.delete(sessionId);
    //   });
    //   this._processExtHostProxies.set(sessionId, proxy);
    //   return {
    //     name: launchConfig.name || 'ExtensionTerminal-' + sessionId,
    //     readonly: false,
    //     onData: proxy.onProcessData.bind(proxy),
    //     sendData: proxy.input.bind(proxy),
    //     onExit: proxy.onProcessExit.bind(proxy),
    //   };
    // }

    return await window.electron.terminal.attachByLaunchConfig(
      sessionId,
      cols,
      rows,
      launchConfig
      // xterm
    );
  }

  /**
   * 获取终端当前工作目录
   * @param sessionId 终端 sessionId
   */
  async getCwd(sessionId: string): Promise<string | undefined> {
    return await window.electron.terminal.getCwd(sessionId);
  }
}
